package com.platform.common.config.shiro;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.platform.common.constants.UserConstants;
import com.platform.common.utils.MD5Utils;
import com.platform.common.utils.SpringUtil;
import com.platform.web.mapper.RolePermissionMapper;
import com.platform.web.mapper.RoleUserMapper;
import com.platform.web.mapper.SysUserMapper;
import com.platform.web.model.Permission;
import com.platform.web.model.Role;
import com.platform.web.model.SysUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author pemgshuiming
 * @date 2018/6/9
 */
public class ShiroRealm extends AuthorizingRealm {

    private static final Logger logger = LoggerFactory.getLogger(ShiroRealm.class);
    @Resource
    SysUserMapper userMapper;
    @Resource
    RolePermissionMapper rolePermissionMapper;
    @Resource
    RoleUserMapper roleUserMapper;
    /**
     * 授权用户权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获取登录时输入的用户名
        String loginName = (String) principalCollection.fromRealm(getName()).iterator().next();
        try {
            //获取用户对象
            SysUser user = new SysUser();
//            SysUser user = userMapper.selectUserByAccount(loginName);
            // 权限信息对象info，用来存放查出的用户的所有的角色（role）及权限（permission）
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            // 获取角色
            List<Role> userRoleList = roleUserMapper.getUserRoleList(user.getId());
            if(userRoleList!=null){
                for (Role role : userRoleList) {
                    info.addRole(role.getRoleCode());
                    // 查找角色权限
                    List<Permission> permissions = new ArrayList<>();
                    List<Permission> permissionList = rolePermissionMapper.getRolePermissionsListByUserId(role.getId());
                    if(permissionList!=null){
                        for (Permission permission : permissionList) {
                            info.addStringPermission(permission.getPermissionCode());
                        }
                    }
                }
            }
            //成功返回
            return info;
        } catch (Exception e) {
            logger.error("[授权异常]",e.getMessage(), e);
        }
        return null;
    }
    /**
     * 用户登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        SysUserMapper userMapper = (SysUserMapper) SpringUtil.getBeanByClass(SysUserMapper.class);
        //获取登录账户密码
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        String password = String.valueOf(token.getPassword());
        try {
            //获取用户对象
            SysUser loginUser = new SysUser();
            loginUser.setAccount(username);
            SysUser user = userMapper.selectOne(loginUser);
            /** 检测是否有此用户 **/
            if (user == null) {
                // 没有找到账号异常
                throw new UnknownAccountException();
            }
            /** 检验密码是否正确 **/
            String md5ofStr = MD5Utils.getMd5ofStr(password);
            if (!md5ofStr.equals(user.getPassword())) {
                throw new IncorrectCredentialsException();
            }
            /** 检验账号是否被锁定 **/
            if (0 == user.getStatus()) {
                // 抛出账号锁定异常
                throw new LockedAccountException();
            }
            /** AuthenticatingRealm使用CredentialsMatcher进行密码匹配 **/
            if (null != username && null != password) {
                Subject sub = SecurityUtils.getSubject();
                sub.getSession().setAttribute(UserConstants.SESSION_KEY,user);
                return new SimpleAuthenticationInfo(username, password, getName());
            } else {
                return null;
            }
        } catch (Exception e) {
            logger.error("[登录异常]",e.getMessage(),e);
        }
        return null;
    }
}
